﻿using GBT.Entity.Base_Manage;
using GBT.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DingTalk.Api.Response;
using GBT.Entity;
using System;
using Elasticsearch.Net;
using System.Collections.Immutable;

namespace GBT.Business.Base_Manage
{
    public class Base_DepartmentBusiness : BaseBusiness<Base_Department>, IBase_DepartmentBusiness, ITransientDependency
    {
        public Base_DepartmentBusiness(IDbAccessor db)
            : base(db)
        {
        }

        DDApi.DDApi ddApi = new DDApi.DDApi();

        #region 外部接口

        public async Task<List<Base_DepartmentTreeDTO>> GetTreeDataListAsync(DepartmentsTreeInputDTO input)
        {
            var where = LinqHelper.True<Base_Department>();
            if (!input.parentId.IsNullOrEmpty())
                where = where.And(x => x.ParentId == input.parentId);

            var list = await GetIQueryable().Where(where).ToListAsync();
            var treeList = list
                .Select(x => new Base_DepartmentTreeDTO
                {
                    Id = x.Id,
                    ParentId = x.ParentId,
                    Text = x.Name,
                    Value = x.Id
                }).ToList();

            return TreeHelper.BuildTree(treeList);
        }

        public async Task<List<string>> GetChildrenIdsAsync(string departmentId)
        {
            var allNode = await GetIQueryable().Select(x => new TreeModel
            {
                Id = x.Id,
                ParentId = x.ParentId,
                Text = x.Name,
                Value = x.Id
            }).ToListAsync();

            var children = TreeHelper
                .GetChildren(allNode, allNode.Where(x => x.Id == departmentId).FirstOrDefault(), true)
                .Select(x => x.Id)
                .ToList();

            return children;
        }

        public async Task<Base_Department> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        [DataRepeatValidate(new string[] { "Name" }, new string[] { "部门名" })]
        [DataAddLog(UserLogType.部门管理, "Name", "部门名")]
        public async Task AddDataAsync(Base_Department newData)
        {
            await InsertAsync(newData);
        }

        [Transactional]
        public async Task SyncDeptDataAsync(Base_Department newData)
        {
            //同步钉钉的部门资料
            List<Base_Department> newDataList_Add = null;
            List<Base_Department> newDataList_Update = null;
            List<Base_Department> newDataList_Delete = null;
            Base_Department _Department = new Base_Department();
            string Id = "";
            var ddToken = ddApi.GetAccessToken();
            var deptList = ddApi.GetDepartmentList(ddToken.AccessToken);
            Console.WriteLine(deptList.ToJson());
            var localDeptList = GetIQueryable().ToList();
            deptList?.ForEach(t =>
            {
                _Department = new Base_Department();
                _Department.Deleted = false;
                _Department.CreatorId = newData.CreatorId;
                _Department.CreateTime = DateTime.Now;

                if (localDeptList.Select(d => d.Id).Contains(t.Id.ToString()))
                {
                    if (newDataList_Update == null)
                    {
                        newDataList_Update = new List<Base_Department>();
                    }
                    if (t.Id == 1 && !t.Name.IsNullOrEmpty())
                    {
                        //跳过本次循环
                        return;
                    }
                    Id = t.Id.ToString();
                    _Department = localDeptList.Where(ld => ld.Id == Id).FirstOrDefault();
                    //修改
                    _Department.Id = t.Id.ToString();
                    _Department.Name = t.Name;
                    _Department.ParentId = t.Parentid.ToString();
                    newDataList_Update.Add(_Department);
                }
                else
                {
                    if (newDataList_Add == null)
                    {
                        newDataList_Add = new List<Base_Department>();
                    }

                    //新增
                    _Department.Id = t.Id.ToString();
                    _Department.Name = t.Name;
                    _Department.ParentId = t.Parentid.ToString();
                    newDataList_Add.Add(_Department);
                }

                if (!t.DeptManagerUseridList.IsNullOrEmpty())
                {
                    string[] deptManagerUseridList = t.DeptManagerUseridList.Split("|");
                    if (!deptManagerUseridList.IsNullOrEmpty())
                    {
                        AddOrModifyDepartmentHeadAsync(deptManagerUseridList, _Department.Id, _Department.CreatorId);
                    }
                }
            });

            localDeptList?.ForEach(t =>
            {
                if (!deptList.Select(d => d.Id).Contains(long.Parse(t.Id)))
                {
                    if (newDataList_Delete == null)
                    {
                        newDataList_Delete = new List<Base_Department>();
                    }
                    //删除
                    newDataList_Delete.Add(t);
                }
            });

            if (newDataList_Add != null)
            {
                await InsertAsync(newDataList_Add);
            }
            if (newDataList_Update != null)
            {
                await UpdateAsync(newDataList_Update);
            }
            if (newDataList_Delete != null)
            {
                await DeleteAsync(newDataList_Delete);
            }
        }

        [DataRepeatValidate(new string[] { "Name" }, new string[] { "部门名" })]
        [DataEditLog(UserLogType.部门管理, "Name", "部门名")]
        public async Task UpdateDataAsync(Base_Department theData)
        {
            await UpdateAsync(theData);
        }

        [DataDeleteLog(UserLogType.部门管理, "Name", "部门名")]
        public async Task DeleteDataAsync(List<string> ids)
        {
            if (await GetIQueryable().AnyAsync(x => ids.Contains(x.ParentId)))
                throw new BusException("禁止删除！请先删除所有子级！");

            await DeleteAsync(ids);
        }

        #endregion

        #region 私有方法

        private int AddOrModifyDepartmentHeadAsync(string[] userIds, string deptId, string creatorId)
        {
            var departmentHeadList = Db.GetIQueryable<Base_DepartmentHead>().Where(t => t.DepartmentId == deptId && userIds.Contains(t.UserId)).ToList();
            Base_DepartmentHead departmentHead = null;
            List<Base_DepartmentHead> departmentHeads = null;
            if (departmentHeadList.Count > 0)
            {
                //存在则更新 系统自动管理的资料 所以直接跳过即可 不需要更新
            }
            else
            {
                //不存在则执行新增操作
                if (departmentHead == null)
                {
                    departmentHead = new Base_DepartmentHead();
                }
                userIds.ForEach(userId =>
                {
                    if (departmentHeads == null)
                    {
                        departmentHeads = new List<Base_DepartmentHead>();
                    }
                    departmentHead.Id = IdHelper.GetId();
                    departmentHead.DepartmentId = deptId;
                    departmentHead.UserId = userId;
                    departmentHead.CreatorId = creatorId;
                    departmentHead.CreateTime = DateTime.Now;
                    departmentHeads.Add(departmentHead);
                });
            }

            if (departmentHeads.IsNullOrEmpty())
            {
                return 0;
            }
            return Db.Insert(departmentHeads);
        }

        #endregion
    }
}